/*
 * Copyright (c) 2015—2030 GantSoftware.Co.Ltd. All rights reserved.
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * is not allowed to be distributed or copied without the license from
 * GantSoftware.Co.Ltd. Please contact the company for more information.
 */
package com.gantang.poc.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.gantang.poc.config.ServerConfigV2;
import com.gantang.poc.mock.MockData;
import com.gantang.poc.req.*;
import com.gantang.poc.task.Api3Task;
import com.gantang.poc.task.ApiTask;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("test")
@Tag(name = "配置点单校验服务")
@Slf4j
public class TestController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ThreadPoolTaskExecutor threadPool;
    @Autowired
    private ServerConfigV2 serverConfigV2;

    @Operation(summary = "测试API1", description = "传入任务编号/产品特征清单")
    @PostMapping("testApi1")
    public String testApi1(String taskId, Integer count) {
        String url = serverConfigV2.getApi1Path();
        taskId = taskId == null ? "test" : taskId;
        count = count == null ? 50 : count;
        for (int i = 0; i < count; i++) {
            ProFeatureTable requestBody = MockData.mockProFeatureTableData();
            String _taskId = taskId + "_" + i;
            requestBody.setReqId(_taskId);
            requestBody.setTaskId(_taskId);
            ApiTask task = new ApiTask(restTemplate, url, requestBody);
            threadPool.submit(task);
//            try {
//                TimeUnit.MILLISECONDS.sleep(100);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
        }
        return "SUCCESS";
    }

    @Operation(summary = "测试API3")
    @PostMapping("testApi3")
    public String testApi3(@RequestParam String taskId, Integer count, Integer randomCount) {
        TimeInterval timer = DateUtil.timer();
        Random random = new Random();
        String url = serverConfigV2.getApi3Path();
        Map<String, List<String>> featureFamilyMap = handleFeatureTableData();
        count = count == null ? 50 : count;
        randomCount = randomCount == null ? 10 : randomCount;
        String[] taskAndCount = taskId.split("_");
        String _taskId = taskAndCount[0];
        int _count = Integer.parseInt(taskAndCount[1]);

        // 用于收集任务的Future对象
        List<Future<Boolean>> futures = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            FeatureSelectReq requestBody = new FeatureSelectReq();
            requestBody.setTaskId(_taskId + "_" + random.nextInt((_count - 1)));
            requestBody.setReqId(UUID.randomUUID().toString());
            requestBody.setCfgFilePath("path");
            requestBody.setCalCount("true");
            requestBody.setSelectedFeatures(randomSelectedFeatures(featureFamilyMap, randomCount));
            Api3Task task = new Api3Task(restTemplate, url, requestBody);
            Future<Boolean> future = threadPool.submit(task);
            futures.add(future);
        }
        // 统计成功的请求数量
        int successCount = 0;
        for (Future<Boolean> future : futures) {
            try {
                if (future.get()) {
                    successCount++;
                }
            } catch (InterruptedException | ExecutionException e) {
                log.error("Error executing task", e);
            }
        }
        // 计算成功率
        double successRate = (double) successCount / count * 100;
        log.info("请求数: {},Success Rate: {}%，共耗时: {}ms", count, successRate, timer.interval());
        return "SUCCESS";
    }

    private Map<String, List<String>> handleFeatureTableData() {
        ProFeatureTable proFeatureTable = MockData.mockProFeatureTableData();
        List<ProFeatureTable.FeatureTableData> featureTableDatas = proFeatureTable.getFeatureTableDatas();
        Map<String, List<String>> featureFamilyMap = featureTableDatas.stream()
                .collect(Collectors.groupingBy(
                        ProFeatureTable.FeatureTableData::getFeatureFamily,
                        Collectors.mapping(ProFeatureTable.FeatureTableData::getFeatureCode, Collectors.toList())
                ));
//        featureFamilyMap.forEach((featureFamily, featureCodes) -> {
//            log.info("Feature Family: " + featureFamily + ", Feature Codes: " + featureCodes);
//        });
        return featureFamilyMap;
    }

    private List<String> randomSelectedFeatures(Map<String, List<String>> featureFamilyMap, Integer randomCount) {
        Random random = new Random();
        // 用于保存最终选中的feature codes
        List<String> selectedFeatureCodes = new ArrayList<>();
        // 处理BASE键
        if (featureFamilyMap.containsKey("BASE")) {
            List<String> baseCodes = featureFamilyMap.get("BASE");
            String selectedBaseCode = baseCodes.get(random.nextInt(baseCodes.size()));
            selectedFeatureCodes.add(selectedBaseCode);
//            log.info("Selected BASE Feature Code: " + selectedBaseCode);
        }
        // 处理其他键
        List<String> nonBaseKeys = featureFamilyMap.keySet().stream()
                .filter(key -> !key.equals("BASE"))
                .collect(Collectors.toList());
        // 生成0到10之间的随机数
        int _randomCount = random.nextInt((randomCount + 1));
//        log.info("Random count: " + randomCount);
        // 随机选择randomCount个不同的非BASE的key
        Collections.shuffle(nonBaseKeys); // 打乱key的顺序
        List<String> selectedKeys = nonBaseKeys.stream()
                .limit(_randomCount)
                .collect(Collectors.toList());
        // 从每个选定的非BASE key的list中随机选择一个featureCode
        selectedKeys.forEach(key -> {
            List<String> codes = featureFamilyMap.get(key);
            String selectedCode = codes.get(random.nextInt(codes.size())); // 随机选择一个featureCode
            selectedFeatureCodes.add(selectedCode);
        });
        // 输出结果
        log.info("Selected Feature Codes: " + selectedFeatureCodes);
        return selectedFeatureCodes;
    }

    private List<String> randomSelectedFeatures2(Map<String, List<String>> featureFamilyMap, Integer randomCount) {
        Random random = new Random();
        // 用于保存最终选中的feature codes
        List<String> selectedFeatureCodes = new ArrayList<>();
        // 处理BASE键
        if (featureFamilyMap.containsKey("BASE")) {
            List<String> baseCodes = featureFamilyMap.get("BASE");
            String selectedBaseCode = baseCodes.get(random.nextInt(baseCodes.size()));
            selectedFeatureCodes.add(selectedBaseCode);
        }

        return selectedFeatureCodes;
    }

    private List<String> randomSelectedFeatures3(Map<String, List<String>> featureFamilyMap, Integer randomCount) {
        Random random = new Random();
        // 用于保存最终选中的feature codes
        List<String> selectedFeatureCodes = new ArrayList<>();

        // 处理其他键
        List<String> nonBaseKeys = featureFamilyMap.keySet().stream()
                .filter(key -> !key.equals("BASE"))
                .collect(Collectors.toList());
        // 生成0到10之间的随机数
        int _randomCount = random.nextInt((randomCount) + 1);
//        log.info("Random count: " + randomCount);
        // 随机选择randomCount个不同的非BASE的key
        Collections.shuffle(nonBaseKeys); // 打乱key的顺序
        List<String> selectedKeys = nonBaseKeys.stream()
                .limit(_randomCount)
                .collect(Collectors.toList());
        // 从每个选定的非BASE key的list中随机选择一个featureCode
        selectedKeys.forEach(key -> {
            List<String> codes = featureFamilyMap.get(key);
            String selectedCode = codes.get(random.nextInt(codes.size())); // 随机选择一个featureCode
            selectedFeatureCodes.add(selectedCode);
        });
        if(CollectionUtil.isEmpty(selectedKeys)){
            selectedFeatureCodes.add("T_ES03");
        }
        // 输出结果
        log.info("Selected Feature Codes: " + selectedFeatureCodes);
        return selectedFeatureCodes;
    }

    @Operation(summary = "测试API4")
    @PostMapping("testApi4")
    public String testApi4(@RequestParam String taskId, Integer count, Integer randomCount) {
        TimeInterval timer = DateUtil.timer();
        Random random = new Random();
        String url = serverConfigV2.getApi4Path();
        Map<String, List<String>> featureFamilyMap = handleFeatureTableData();
        count = count == null ? 50 : count;
        randomCount = randomCount == null ? 10 : randomCount;
        String[] taskAndCount = taskId.split("_");
        String _taskId = taskAndCount[0];
        int _count = Integer.parseInt(taskAndCount[1]);

        // 用于收集任务的Future对象
        List<Future<Boolean>> futures = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            FeatureSelectLimitReq featureSelectLimitReq = new FeatureSelectLimitReq();
            featureSelectLimitReq.setTaskId(_taskId + "_" + random.nextInt((_count - 1)));
//            featureSelectLimitReq.setTaskId("bdd_test001");
            featureSelectLimitReq.setReqId(UUID.randomUUID().toString());
            featureSelectLimitReq.setCfgFilePath("path");
            featureSelectLimitReq.setLimitCount(random.nextInt(500) + 1);
            featureSelectLimitReq.setSelectedFeatures(randomSelectedFeatures(featureFamilyMap, randomCount));
            Api3Task task = new Api3Task(restTemplate, url, featureSelectLimitReq);
            Future<Boolean> future = threadPool.submit(task);
            futures.add(future);
        }
        // 统计成功的请求数量
        int successCount = 0;
        for (Future<Boolean> future : futures) {
            try {
                if (future.get()) {
                    successCount++;
                }
            } catch (InterruptedException | ExecutionException e) {
                log.error("Error executing task", e);
            }
        }
        // 计算成功率
        double successRate = (double) successCount / count * 100;
        log.info("请求数: {},Success Rate: {}%，共耗时: {}ms", count, successRate, timer.interval());
        return "SUCCESS";
    }

    @Operation(summary = "测试API5")
    @PostMapping("testApi5")
    public String testApi5(@RequestParam String taskId, Integer count, Integer randomCount) {
        TimeInterval timer = DateUtil.timer();
        Random random = new Random();
        String url = serverConfigV2.getApi5Path();
        Map<String, List<String>> featureFamilyMap = handleFeatureTableData();
        count = count == null ? 50 : count;
        randomCount = randomCount == null ? 10 : randomCount;
        String[] taskAndCount = taskId.split("_");
        String _taskId = taskAndCount[0];
        int _count = Integer.parseInt(taskAndCount[1]);

        // 用于收集任务的Future对象
        List<Future<Boolean>> futures = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            FeatureSelectSpecFamilyLimitReq featureSelectLimitReq = new FeatureSelectSpecFamilyLimitReq();
            featureSelectLimitReq.setTaskId(_taskId + "_" + random.nextInt((_count - 1)));
            featureSelectLimitReq.setReqId(UUID.randomUUID().toString());
            featureSelectLimitReq.setCfgFilePath("path");
            featureSelectLimitReq.setLimitCount(random.nextInt(500) + 1);
//            List<String> featureList = randomSelectedFeatures3(featureFamilyMap, randomCount);
            List<String> featureFamilyList = new ArrayList<>();
            featureFamilyList.add("T_AK");
            featureSelectLimitReq.setSpecifiedFamilies(featureFamilyList);
//            featureSelectLimitReq.setSelectedFeatures(featureList);
            Api3Task task = new Api3Task(restTemplate, url, featureSelectLimitReq);
            Future<Boolean> future = threadPool.submit(task);
            futures.add(future);
        }
        // 统计成功的请求数量
        int successCount = 0;
        for (Future<Boolean> future : futures) {
            try {
                if (future.get()) {
                    successCount++;
                }
            } catch (InterruptedException | ExecutionException e) {
                log.error("Error executing task", e);
            }
        }
        // 计算成功率
        double successRate = (double) successCount / count * 100;
        log.info("请求数: {},Success Rate: {}%，共耗时: {}ms", count, successRate, timer.interval());
        return "SUCCESS";
    }


    @Operation(summary = "测试API6")
    @PostMapping("testApi6")
    public String testApi6(@RequestParam String taskId, Integer count, Integer randomCount) {
        TimeInterval timer = DateUtil.timer();
        Random random = new Random();
        String url = serverConfigV2.getApi6Path();
        Map<String, List<String>> featureFamilyMap = handleFeatureTableData();
        count = count == null ? 50 : count;
        randomCount = randomCount == null ? 10 : randomCount;
        String[] taskAndCount = taskId.split("_");
        String _taskId = taskAndCount[0];
        int _count = Integer.parseInt(taskAndCount[1]);

        // 用于收集任务的Future对象
        List<Future<Boolean>> futures = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            RecommendVehicleReq featureSelectLimitReq = new RecommendVehicleReq();
            featureSelectLimitReq.setTaskId(_taskId + "_" + random.nextInt((_count - 1)));
//            featureSelectLimitReq.setTaskId("bdd_test001");
            featureSelectLimitReq.setReqId(UUID.randomUUID().toString());
            featureSelectLimitReq.setCfgFilePath("path");
            List<String> featureList = randomSelectedFeatures3(featureFamilyMap, randomCount);
            featureSelectLimitReq.setSelectedFeatures(featureList);
            Api3Task task = new Api3Task(restTemplate, url, featureSelectLimitReq);
            Future<Boolean> future = threadPool.submit(task);
            futures.add(future);
        }
        // 统计成功的请求数量
        int successCount = 0;
        for (Future<Boolean> future : futures) {
            try {
                if (future.get()) {
                    successCount++;
                }
            } catch (InterruptedException | ExecutionException e) {
                log.error("Error executing task", e);
            }
        }
        // 计算成功率
        double successRate = (double) successCount / count * 100;
        log.info("请求数: {},Success Rate: {}%，共耗时: {}ms", count, successRate, timer.interval());
        return "SUCCESS";
    }
}
